﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;

namespace PuzzleCoop
{
    public static class Input
    {
        static KeyboardState keyboardState;
        static KeyboardState keyboardPrevState;

        static GamePadState[] gamePadState = new GamePadState[4];
        static GamePadState[] gamePadPrevState = new GamePadState[4];
        static double[] vibrationTimer = new double[4] { 0, 0, 0, 0 };

        static MouseState mouseState;
        static MouseState mousePrevState;


        public static void Start()
        {
            mousePrevState = mouseState = Mouse.GetState();
            keyboardPrevState = keyboardState = Keyboard.GetState();
            gamePadPrevState[0] = gamePadState[0] = GamePad.GetState(PlayerIndex.One);
            gamePadPrevState[1] = gamePadState[1] = GamePad.GetState(PlayerIndex.Two);
        }

        public static void Update(GameTime gameTime)
        {
            UpdatePrevStates();
            keyboardState = Keyboard.GetState();
            mouseState = Mouse.GetState();
            for (int i = 0; i < 4; ++i) gamePadState[i] = GamePad.GetState((PlayerIndex)i);
            UpdateVibration(gameTime);

            if (ButtonPressed(0, Buttons.Back) || KeyPressed(Keys.Escape)) GameScreenManager.game.Exit();
            if (KeyPressed(Keys.F1)) GameScreenManager.Reset();
        }

        public static void UpdatePrevStates()
        {
            keyboardPrevState = keyboardState;
            mousePrevState = mouseState;
            for (int i = 0; i < 4; ++i) gamePadPrevState[i] = gamePadState[i];
        }

        #region GamePad
        public static Vector2 LeftStickState(int i)
        {
            Vector2 d = Vector2.Zero;
            d = gamePadState[i].ThumbSticks.Left;
            d.Y *= -1;
            if (d != Vector2.Zero) d.Normalize();
            return d;
        }

        public static Vector2 RightStickState(int i)
        {
            Vector2 d = Vector2.Zero;
            d = gamePadState[i].ThumbSticks.Right;
            d.Y *= -1;
            if (d != Vector2.Zero) d.Normalize();
            return d;
        }

        public static bool ButtonPressed(int i, Buttons b)
        {
            return gamePadState[i].IsButtonDown(b) && gamePadPrevState[i].IsButtonUp(b);
        }

        public static bool ButtonDown(int i, Buttons b)
        {
            return gamePadState[i].IsButtonDown(b);
        }

        public static void Vibrate(int playerIndex, int time)
        {
            if (time > vibrationTimer[playerIndex])
            {
                GamePad.SetVibration((PlayerIndex)playerIndex, 1f, 1f);
                vibrationTimer[playerIndex] = time;
            }
        }

        public static void UpdateVibration(GameTime gameTime)
        {
            for (int i = 0; i < 4; ++i)
            {
                if (vibrationTimer[i] < 0) continue;
                vibrationTimer[i] -= gameTime.ElapsedGameTime.TotalMilliseconds;
                if (vibrationTimer[i] < 0) GamePad.SetVibration((PlayerIndex)i, 0f, 0f);
            }
        }
        #endregion

        #region Input --- Keyboard
        public static bool KeyPressed(Keys k)
        {
            return keyboardState.IsKeyDown(k) && keyboardPrevState.IsKeyUp(k);
        }

        public static bool KeyDown(Keys k)
        {
            return keyboardState.IsKeyDown(k);
        }
        #endregion

        #region Input --- Mouse
        public static bool MouseClick
        {
            get
            {
                return mouseState.LeftButton == ButtonState.Pressed && mousePrevState.LeftButton == ButtonState.Released;
            }
        }

        public static bool MouseRClick
        {
            get
            {
                return mouseState.RightButton == ButtonState.Pressed && mousePrevState.RightButton == ButtonState.Released;
            }
        }

        public static Vector2 MousePos
        {
            get
            {
                return new Vector2(mouseState.X, mouseState.Y);
            }
        }

        #endregion

        #region Input --- Virtual Keyboard
        private static String VKresult = null;
        public static String GetVKResult
        {
            get
            {
                if (VKresult != null)
                {
                    String temp = VKresult;
                    VKresult = null;
                    return temp;
                }
                return null;
            }
        }

        public static void CallVK()
        {
            Guide.BeginShowKeyboardInput(PlayerIndex.One, "Name", "Enter your name:", "", new AsyncCallback(EndVirtualKeyboardInput), null);
            VKresult = "WAITING";
            //GamerServicesDispatcher.Update();
        }

        private static void EndVirtualKeyboardInput(IAsyncResult result)
        {
            VKresult = Guide.EndShowKeyboardInput(result);
            if (VKresult == null) VKresult = "CANCEL";
        }
        #endregion

        public static GameTime gameTime { get; set; }
    }
}
